package dwei.textwrap
{
	import flash.events.Event;
	import flash.text.TextFormat;
	
	import mx.core.UIComponent;
	
	import dwei.textwrap.wrapper.Wrapper;
	import dwei.textwrap.wrapper.WrapperChar;
	import dwei.textwrap.wrapper.WrapperGraphics;
	import dwei.textwrap.wrapper.WrapperLineFeed;

	/**
	 * 图文混排UI<br/>
	 * 属性 <code>text</code> 中可用\n(或者\r、\r\n)进行换行
	 */	
	public class WrapperUI extends UIComponent
	{
//============================================================================
//PROPERTY
//============================================================================
		protected const LINE_FEED:String = "\n";
		
		protected var _parser:IWrapperParser;
		
		private var _textChanged:Boolean = false;
		protected var _text:String;
		
		private var _formatChanged:Boolean = false;
		protected var _textWrapFormat:WrapperFormat;
		
		protected const _wrappers:Array = [];
//============================================================================
//CONSTRUCTOR
//============================================================================
		public function WrapperUI()
		{
			super();
			explicitWidth = 100;
			
			_parser = new WrapperParserDefault();
			
			_textWrapFormat = new WrapperFormat();
			_textWrapFormat.addEventListener(Event.CHANGE, textWrapFormatChanged_handler);
		}
//============================================================================
//OVERRIDE
//============================================================================
		override protected function commitProperties():void
		{
			super.commitProperties();
			if (_textChanged)
			{
				removeAllChildren();
				_wrappers.length = 0;
				decodeText(_text, _wrappers, 0);
				invalidateFormat();
				_textChanged = false;
			}
			if (_formatChanged)
			{
				validateFormat();
				_formatChanged = false;
			}
		}
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			validateLayout();
		}
//============================================================================
//PUBLIC
//============================================================================
		public function removeAllChildren():void
		{
			var wrapper:Wrapper;
			while (numChildren > 0)
			{
				wrapper = removeChildAt(0) as Wrapper;
			}
		}
		public function invalidateFormat():void
		{
			_formatChanged = true;
			invalidateProperties();
		}
//============================================================================
//PROTECTED
//============================================================================
		/**
		 * 将指定的字符串转换成对应的Wrapper并添加到容器container的指定位置
		 * @param text
		 * @param container
		 * @param curIndex
		 * 
		 */		
		protected function decodeText(text:String, container:Array, curIndex:int):void
		{
			var vo:WrapperVO;
			var wrapper:Wrapper;
			while (text.length > 0)
			{
				if (text.indexOf(LINE_FEED) == 0)
				{
					vo = new WrapperVO(WrapperType.LINE_FEED, LINE_FEED);
					wrapper = new WrapperLineFeed();
				}
				else
				{
					vo = _parser.getHeadTextWrap(text);
					if (vo.type == WrapperType.TEXT)
					{
						wrapper = new WrapperChar();
						WrapperChar(wrapper).char = vo.head;
					}
					else if (vo.type == WrapperType.GRAPHICS)
					{
						wrapper = new WrapperGraphics();
						WrapperGraphics(wrapper).source = vo.data;
					}
				}
				wrapper.verticalAlign = vo.align;
				container.splice(curIndex, 0, wrapper);
				addChildAt(wrapper, curIndex);
				text = text.substr(vo.head.length);
				curIndex++;
			}
		}
		/**
		 * 对当前的所有Wrapper应用样式
		 * 
		 */		
		protected function validateFormat():void
		{
			var wrapper:Wrapper;
			var textFormat:TextFormat = new TextFormat();
			textFormat.size = _textWrapFormat.fontSize;
			textFormat.color = _textWrapFormat.fontColor;
			textFormat.font = _textWrapFormat.fontFamily;
			textFormat.bold = _textWrapFormat.fontBold;
			textFormat.italic = _textWrapFormat.fontItalic;
			textFormat.underline = _textWrapFormat.fontUnderLine;
			for each (wrapper in _wrappers)
			{
				if (wrapper is WrapperChar) WrapperChar(wrapper).textFormat = textFormat;
			}
		}
		/**
		 * 布局
		 * 
		 */		
		protected function validateLayout():void
		{
			var len:int = _wrappers.length;
			if (len == 0) return;
			
			var x:int = _textWrapFormat.indent + _textWrapFormat.paddingLeft;
			var y:int = _textWrapFormat.paddingTop;
			var wrapper:Wrapper = _wrappers[0];
			wrapper.move(x, y);
			
			if (wrapper is WrapperLineFeed) x = int.MAX_VALUE;
			else x += wrapper.measuredWidth + _textWrapFormat.letterGap;
			
			var line:Array = [wrapper];
			var lineHeight:int = wrapper.measuredHeight;
			for (var index:int = 1;index < len;index++)
			{
				wrapper = _wrappers[index];
				if (x + wrapper.measuredWidth + _textWrapFormat.paddingRight > unscaledWidth)
				{
					validateLineHeight(line, lineHeight);
					x = _textWrapFormat.paddingLeft;
					y += lineHeight + _textWrapFormat.leading;
					
					line.length = 0;
					lineHeight = 0;
				}
				wrapper.move(x, y);
				lineHeight = Math.max(lineHeight, wrapper.measuredHeight);
				
				if (wrapper is WrapperLineFeed) x = int.MAX_VALUE;
				else x += wrapper.measuredWidth + _textWrapFormat.letterGap;
				
				line.push(wrapper);
			}
			validateLineHeight(line, lineHeight);
		}
		/**
		 * 设置每行中Wrapper的行高
		 * @param line
		 * @param height
		 * 
		 */		
		protected function validateLineHeight(line:Array, height:int):void
		{
			for each (var wrapper:Wrapper in line)
			{
				wrapper.setActualSize(wrapper.measuredWidth, height);				
			}
		}
//============================================================================
//HANDLER
//============================================================================
		private function textWrapFormatChanged_handler(event:Event):void
		{
			invalidateFormat();
		}
//============================================================================
//GETTER/SETTER
//============================================================================
		/**
		 * 可以由IWrapperParser解析的字符串
		 */		
		public function get text():String
		{
			return _text;
		}
		/**
		 * @private
		 */		
		public function set text(value:String):void
		{
			if (value == null) value = "";
			value = value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
			if (value == _text) return;
			_text = value;
			_textChanged = true;
			invalidateProperties();
		}
		/**
		 * 字符串显示样式
		 */		
		public function get textWrapFormat():WrapperFormat
		{
			return _textWrapFormat;
		}
		/**
		 * 字符串解析器，默认为WrapperParserDefault
		 */		
		public function get parser():IWrapperParser
		{
			return _parser;
		}
		/**
		 * @private
		 */		
		public function set parser(value:IWrapperParser):void
		{
			if ((value == null) || (value == _parser)) return;
			_parser = value;
		}


	}
}